﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;
using OctoOS.Services;
using OctoOS;
using System.ServiceModel.Syndication;
using System.Web;

[DataContract]
public class SaveHtmlResponse : BasicAjaxResponse
{
	[DataMember(EmitDefaultValue = false)]
	public string[] errors;

	internal SaveHtmlResponse(string[] errors)
	{
		this.errors = errors;
	}

	internal SaveHtmlResponse(string errorMessage)
		: base(errorMessage)
	{
		//errors = new string[0];
	}
}

[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class AjaxSectionService
{
	[OperationContract]
	[WebInvoke(Method = "POST",
				BodyStyle = WebMessageBodyStyle.Wrapped,
				ResponseFormat = WebMessageFormat.Json,
				RequestFormat = WebMessageFormat.Json)]
	public SaveHtmlResponse SaveHtml(string title, string body, string articleID,
		string pageID)
	{
		var aID = Convert.ToInt64(articleID);
		long pID = Convert.ToInt64(pageID);

#warning moder
		var article = ApiService.GetArticle(OOSRequest.Current, aID);
		if(!OOSRequest.Current.IsModerator &&
				article.UserID != OOSRequest.Current.UserID)
		{
			throw new HttpException();
		}

		

		string errorMessage = string.Empty;

		try
		{
			ApiService.InsertSection(OOSRequest.Current, aID, pID,
				title, body, TextFormat.Html);
		}
		catch(Exception ex)
		{
			errorMessage = ex.Message;
		}

		return new SaveHtmlResponse(errorMessage);
	}


	[OperationContract]
	[WebInvoke(Method = "POST",
		ResponseFormat = WebMessageFormat.Json,
		RequestFormat = WebMessageFormat.Json,
		BodyStyle = WebMessageBodyStyle.Wrapped)]
	public void SavePagesOrder(string pagesOrder, string articleID)
	{
		long artID = Convert.ToInt64(articleID);

		var article = ApiService.GetArticle(OOSRequest.Current, artID);
		if(!OOSRequest.Current.IsModerator &&
				article.UserID != OOSRequest.Current.UserID)
		{
			throw new HttpException();
		}

		string[] pagesIDString = pagesOrder.Split(',');

		List<long> newPagesOrder = new List<long>();
		foreach(var pageIDString in pagesIDString)
		{
			long pageID = Convert.ToInt64(pageIDString);
			newPagesOrder.Add(pageID);
		}

		ApiService.SavePagesOrder(OOSRequest.Current, artID, newPagesOrder.ToArray());
	}

	[OperationContract]
	[WebInvoke(ResponseFormat = WebMessageFormat.Json,
		RequestFormat = WebMessageFormat.Json,
		BodyStyle = WebMessageBodyStyle.Wrapped)]
	public void SaveSectionsOrder(string sectionOrder, string articleID)
	{
		long artID = Convert.ToInt64(articleID);
		var article = ApiService.GetArticle(OOSRequest.Current, artID);
		if(!OOSRequest.Current.IsModerator &&
				article.UserID != OOSRequest.Current.UserID)
		{
			throw new HttpException();
		}

		string[] sectionsID = sectionOrder.Split(',');
		long pageID = 0;
		List<long> newSectionsOrder = new List<long>();
		foreach(var sectionID in sectionsID)
		{
			string[] data = sectionID.Split('_');
			if(pageID == 0)
				pageID = Convert.ToInt64(data[0]);

			newSectionsOrder.Add(Convert.ToInt64(data[1]));
		}

		ApiService.SaveSectionsOrder(OOSRequest.Current, artID, pageID,
			newSectionsOrder.ToArray());
	}

	[OperationContract]
	[WebInvoke(ResponseFormat = WebMessageFormat.Json,
		RequestFormat = WebMessageFormat.Json,
		BodyStyle = WebMessageBodyStyle.Wrapped)]
	public void DeleteSection(string articleID, string pageID, string sectionID)
	{
		long aID = Convert.ToInt64(articleID);
		long pID = Convert.ToInt64(pageID);
		long sID = Convert.ToInt64(sectionID);

		var article = ApiService.GetArticle(OOSRequest.Current, aID);
		if(!OOSRequest.Current.IsModerator &&
				article.UserID != OOSRequest.Current.UserID)
		{
			throw new HttpException();
		}

		ApiService.DeleteSection(OOSRequest.Current, aID, pID, sID);
	}

	[OperationContract]
	[WebInvoke(ResponseFormat = WebMessageFormat.Json,
		RequestFormat = WebMessageFormat.Json,
		BodyStyle = WebMessageBodyStyle.Wrapped)]
	public void DeletePage(string articleID, string pageID)
	{
		long aID = Convert.ToInt64(articleID);
		long pID = Convert.ToInt64(pageID);

		var article = ApiService.GetArticle(OOSRequest.Current, aID);
		if(!OOSRequest.Current.IsModerator &&
				article.UserID != OOSRequest.Current.UserID)
		{
			throw new HttpException();
		}

		ApiService.DeletePage(OOSRequest.Current, aID, pID);
	}


	[OperationContract]
	[WebGet]
	public Rss20FeedFormatter GetMainRss()
	{
		var resourceInfo = AppUtil.GetResourceInfo(OOSRequest.Current);

		var settings = resourceInfo.Settings;
		if(settings.FeedMode == FeedMode.None)
			return null;

#warning избавиться от GetArticles(id1, id2, id3)
		var previews = AppUtil.GetMainRss(OOSRequest.Current);
		if(previews.Length == 0)
			return null;

		Article[] articles = new Article[0];
		if(settings.FeedMode == FeedMode.Full)
		{
			List<long> articlesID = new List<long>();
			foreach (var preview in previews)
				articlesID.Add(preview.ID);

#warning rss
			//articles = ApiService.GetArticles(OOSRequest.Current, articlesID.ToArray());
		}

		SyndicationFeed feed = new SyndicationFeed(
			"Articles Feed",
			"Main articles feed",
			new Uri(@"http://" + OOSRequest.Current.DomainName +
			        OOSRequest.Current.GetContextPath("/") +
			        Urls.Ajax.GetMainRss(false),
			        UriKind.Absolute));

		feed.Authors.Add(new SyndicationPerson("dmitry.pasyutin@yandex.ru"));
		feed.ElementExtensions.Add("ttl", "", "60");
		feed.ImageUrl = new Uri("/images/rss.gif", UriKind.Relative);

		List<SyndicationItem> items = new List<SyndicationItem>();
		foreach (var preview in previews)
		{
			string url = @"http://" + OOSRequest.Current.DomainName +
			             OOSRequest.Current.GetContextPath("/") +
			             Urls.GetArticle(preview.ID, false, false, preview.Title);


			string content = string.Empty;
			if(settings.FeedMode == FeedMode.Short)
			{
				string readMoreTag = String.Format(
					"<br/><br/><a href='{0}'>Читать дальше &rarr;</a>", url);

				content = HttpUtility.HtmlEncode(preview.Preface) + readMoreTag;
			}
			else
			{
				var currentArticle = articles.FirstOrDefault(f => f.ID == preview.ID);
				if(currentArticle != null)
				{
					foreach (var page in currentArticle.GetPages(false))
					{
						foreach (var section in page.Sections)
						{
							content += HttpUtility.HtmlEncode(section.Text);
							content += '\n';
						}

						content += '\n' + '\n';
					}
				}
			}

			var item = new SyndicationItem(
				HttpUtility.HtmlEncode(preview.Title),
				content,
				new Uri(url, UriKind.Absolute),
				preview.ID.ToString(),
				preview.PublishStartTime);

			foreach (var categoryID in preview.CategoryIDs)
			{
				var catName = AppUtil.GetCategory(resourceInfo.Categories, categoryID).Title;
				if(!String.IsNullOrEmpty(catName))
				{
					item.Categories.Add(new SyndicationCategory(
					                    	HttpUtility.HtmlEncode(catName)));
				}
			}

			item.AddPermalink(new Uri(url, UriKind.Absolute));
			item.PublishDate = preview.PublishStartTime;
			item.ElementExtensions.Add("author", "", HttpUtility.HtmlEncode(preview.Author));
			items.Add(item);
		}

		feed.Items = items;

		return new Rss20FeedFormatter(feed, false);
	}

	[OperationContract]
	[WebGet(UriTemplate = "GetRss?category={id}")]
	public Rss20FeedFormatter GetRss(string id)
	{
		var resourceInfo = AppUtil.GetResourceInfo(OOSRequest.Current);

		var settings = resourceInfo.Settings;
		if(settings.FeedMode == FeedMode.None)
			return null;

		long categoryID = Convert.ToInt64(id);
		var category = AppUtil.GetCategory(resourceInfo.Categories, categoryID);
		if(category == null)
			return null;

		var previews = AppUtil.GetCategoryRss(OOSRequest.Current, categoryID);
		if(previews.Length == 0)
			return null;

		Article[] articles = new Article[0];
		if(settings.FeedMode == FeedMode.Full)
		{
			List<long> articlesID = new List<long>();
			foreach (var preview in previews)
				articlesID.Add(preview.ID);
#warning rss
			//articles = ApiService.GetArticles(OOSRequest.Current, articlesID.ToArray());
		}

		SyndicationFeed feed = new SyndicationFeed(
			category.Title,
			"Articles of category \"" + HttpUtility.HtmlEncode(category.Title) + "\"",
			new Uri(@"http://" + OOSRequest.Current.DomainName +
			        OOSRequest.Current.GetContextPath("/") +
			        Urls.Ajax.GetCategoryRss(categoryID, false),
			        UriKind.Absolute));

		feed.ImageUrl = new Uri("/images/rss.gif", UriKind.Relative);
		feed.Authors.Add(new SyndicationPerson("dmitry.pasyutin@yandex.ru"));
		feed.Categories.Add(new SyndicationCategory(HttpUtility.HtmlEncode(category.Title)));
		feed.ElementExtensions.Add("ttl", "", "60");

		List<SyndicationItem> items = new List<SyndicationItem>();
		foreach (var preview in previews)
		{
			string url = @"http://" + OOSRequest.Current.DomainName +
			             OOSRequest.Current.GetContextPath("/") +
			             Urls.GetArticle(preview.ID, false, false, preview.Title);

			string content = string.Empty;
			if(settings.FeedMode == FeedMode.Short)
			{
				string readMoreTag = String.Format(
					"<br/><br/><a href='{0}'>Читать дальше &rarr;</a>", url);

				content = HttpUtility.HtmlEncode(preview.Preface) + readMoreTag;
			}
			else
			{
				var currentArticle = articles.FirstOrDefault(f => f.ID == preview.ID);
				if(currentArticle != null)
				{
					foreach (var page in currentArticle.GetPages(false))
					{
						foreach (var section in page.Sections)
						{
							content += section.Text;
							content += '\n';
						}

						content += '\n' + '\n';
					}
				}
			}


			var item = new SyndicationItem(
				HttpUtility.HtmlEncode(preview.Title),
				content,
				new Uri(url, UriKind.Absolute),
				preview.ID.ToString(),
				preview.PublishStartTime);

			item.AddPermalink(new Uri(url, UriKind.Absolute));
			item.PublishDate = preview.PublishStartTime;
			item.ElementExtensions.Add("author", "", preview.Author);
			item.Categories.Add(new SyndicationCategory(HttpUtility.HtmlEncode(category.Title)));
			items.Add(item);
		}

		feed.Items = items;

		return new Rss20FeedFormatter(feed, false);
	}

	//[OperationContract]
	//[WebInvoke(ResponseFormat = WebMessageFormat.Json,
	//RequestFormat = WebMessageFormat.Json, 
	//BodyStyle = WebMessageBodyStyle.WrappedRequest)]
	//public GetSectionResponse GetSection(string token)
	//{
	//    var parsedToken = ContletToken.Create(token);
	//    var threadID = parsedToken.ThreadID;
	//    var contletID = parsedToken.ContletID;

	//    var response = OctoServices.Process(OOSRequest.Current,
	//       new Post_GetBodies(threadID, contletID));

	//    var threadResponse = response.CastOrHttpException<Post_GetBodies_Response>();
	//    return new GetSectionResponse("title", threadResponse.Bodies[0].Text);
	//}


//    [OperationContract]
//    [WebInvoke(ResponseFormat = WebMessageFormat.Json,
//      RequestFormat = WebMessageFormat.Json, 
//      BodyStyle = WebMessageBodyStyle.WrappedRequest)]
//    public BasicAjaxResponse SaveSection(string token, string title, string body, 
//        string page)
//    {
//#warning moder
//        //OOSRequest.Current.EnsureModerator();

//        var parsedToken = ContletToken.Create(token);
//        var threadID = parsedToken.ThreadID;
//        var pageID = Convert.ToInt64(page);
//        var format = (TextFormat)parsedToken.BodyFormat;

//        ApiService.InsertSection(OOSRequest.Current, threadID, pageID, title,
//            body, format);

//        return new BasicAjaxResponse();
//    }
}

//[DataContract]
// public class GetSectionResponse : BasicAjaxResponse
// {
//  [DataMember(EmitDefaultValue = false)]
//  public string title;

//  [DataMember(EmitDefaultValue = false)]
//  public string body;

//  public GetSectionResponse(string title, string body)
//   : base(null)
//  {
//   this.title = title;
//   this.body = body;
//  }
// }

